package com.bill99.testmp.testmanage.orm.dao.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.CacheMode;
import org.hibernate.Session;
import org.springframework.beans.BeanUtils;

import com.bill99.seashell.orm.hibernate.BaseDaoSupport;
import com.bill99.testmp.testmanage.orm.dao.TaSvnClassDao;
import com.bill99.testmp.testmanage.orm.entity.TaSvnClass;
import com.bill99.testmp.testmanage.orm.entity.TaSvnMethod;

public class TaSvnClassDaoImpl extends BaseDaoSupport<TaSvnClass, Long> implements TaSvnClassDao {
	private static Log logger = LogFactory.getLog(TaSvnClassDaoImpl.class);

	private final int BATCH_IMPORT_SIZE = 500;

	private final String queryTaSvnClass4rv = "select idSvnClass from TaSvnClass where idTaProject = ?";
	private final String queryTaSvnMethod4rv = "select tm.idSvnMethod from TaSvnClass tc,TaSvnMethod tm where tc.idSvnClass=tm.idSvnClass and tc.idTaProject = ?";

	public List<Long> bath4merge(List<TaSvnClass> svnTaPaths, Long idTaProject) {

		List<Long> originalIds = find(queryTaSvnClass4rv, idTaProject);
		List<Long> currentIds = new ArrayList<Long>();
		TaSvnClass taSvn = null;
		Session session = getSession();
		session.setCacheMode(CacheMode.IGNORE);
		int rows = 0;
		if (svnTaPaths.size() == 0) {
			return originalIds;
		}
		session.beginTransaction();
		for (TaSvnClass svnTaPath : svnTaPaths) {
			try {
				taSvn = (TaSvnClass) session.createQuery(query4PackageClass).setParameter(0, svnTaPath.getPackageName()).setParameter(1, svnTaPath.getClassName())
						.setParameter(2, svnTaPath.getIdTaProject()).setMaxResults(1).uniqueResult();
				if (taSvn != null) {
					BeanUtils.copyProperties(svnTaPath, taSvn, new String[] { "idSvnClass" });
					session.update(taSvn);
					currentIds.add(taSvn.getIdSvnClass());
				} else {
					session.save(svnTaPath);
				}
				rows++;
			} catch (Exception e) {
				logger.error(e);
			}
			if (rows % BATCH_IMPORT_SIZE == 0) {
				session.flush();
				session.clear();
				session.getTransaction().commit();
			}

		}

		originalIds.removeAll(currentIds);

		//		for (Long originalId : originalIds) {
		//
		//			session.createQuery(rvClass).setParameter(0, originalId);
		//		}
		if (rows % BATCH_IMPORT_SIZE != 0) {
			session.flush();
			session.clear();
			session.getTransaction().commit();
		}
		releaseSession(session);
		logger.debug("class rows = " + rows);
		return originalIds;

	}

	private final String rvClass = "delete from TaSvnClass where idSvnClass=? ";

	private final String query4method = "from TaSvnMethod where methodName = ? and idSvnClass = ?";

	public List<Long> bath4mergeMethod(List<TaSvnClass> svnTaPaths, Long idTaProject) {

		List<Long> originalIds = find(queryTaSvnMethod4rv, idTaProject);
		List<Long> currentIds = new ArrayList<Long>();

		TaSvnClass taSvn = null;
		TaSvnMethod taMethod = null;
		Session session = getSession();
		session.setCacheMode(CacheMode.IGNORE);
		int rows = 0;
		if (svnTaPaths.size() == 0) {
			return originalIds;
		}
		session.beginTransaction();
		for (TaSvnClass svnTaPath : svnTaPaths) {
			taSvn = (TaSvnClass) session.createQuery(query4PackageClass).setParameter(0, svnTaPath.getPackageName()).setParameter(1, svnTaPath.getClassName())
					.setParameter(2, svnTaPath.getIdTaProject()).setMaxResults(1).uniqueResult();
			for (TaSvnMethod taSvnMethod : svnTaPath.getTaSvnMethods()) {
				try {

					taMethod = (TaSvnMethod) session.createQuery(query4method).setParameter(0, taSvnMethod.getMethodName()).setParameter(1, taSvn.getIdSvnClass()).setMaxResults(1)
							.uniqueResult();
					if (taMethod != null) {
						taMethod.setMemo(taSvnMethod.getMemo());
						taMethod.setDependsOnMethods(taSvnMethod.getDependsOnMethods());
						session.update(taMethod);
						currentIds.add(taMethod.getIdSvnMethod());
					} else {
						taSvnMethod.setIdSvnClass(taSvn.getIdSvnClass());
						session.save(taSvnMethod);
					}
					rows++;
				} catch (Exception e) {
					logger.error(e);
				}
			}
			if (rows % BATCH_IMPORT_SIZE == 0) {
				session.flush();
				session.clear();
				session.getTransaction().commit();
			}
		}
		originalIds.removeAll(currentIds);
		if (rows % BATCH_IMPORT_SIZE != 0) {
			session.flush();
			session.clear();
			session.getTransaction().commit();
		}
		releaseSession(session);
		logger.debug("method rows = " + rows);
		return originalIds;

	}

	private final String rvClassMethod = "delete from TaSvnMethod where idSvnClass=? ";
	private final String rvMethod = "delete from TaSvnMethod where idSvnMethod=? ";

	private final String query4PackageClass = "from TaSvnClass where packageName = ? and className = ? and idTaProject = ?";

	public TaSvnClass query(String packageName, String className, Long testProjectId) {
		return findUnique(query4PackageClass, packageName, className, testProjectId);
	}

	public void deleteClass(Long idSvnClass) {
		execute(rvClass, idSvnClass);
		execute(rvClassMethod, idSvnClass);
		execute(deleteAssoByClass, idSvnClass);
	}

	public void deleteMethod(Long idSvnMethod) {
		execute(rvMethod, idSvnMethod);
		execute(deleteAssoByMethod, idSvnMethod);
	}

	private final String deleteAssoByClass = "delete from AssoTaSvnTestCase att where att.idSvnMethod in ( select tm.idSvnMethod from TaSvnMethod tm where tm.idSvnClass=?  )";
	private final String deleteAssoByMethod = "delete from AssoTaSvnTestCase where idSvnMethod=? ";

}
